package com.mapaoer.user.service.impl;

import com.mapaoer.user.dao.UserRepository;
import com.mapaoer.user.dto.LoginDTO;
import com.mapaower.user.dto.*;
import com.mapaoer.user.dto.UpdateProfileDTO;
import com.mapaoer.user.entity.User;
import com.mapaoer.user.service.UserService;
import com.mapaoer.user.dto.RegisterDTO;
import com.mapaower.user.utils.JwtTokenProvider;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import com.mapaower.user.security.UserPrincipal;
import org.springframework.security.crypto.password.PasswordEncoder;
import java.util.Date;
import java.time.LocalDateTime;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.util.Map;
import java.util.Random;

import java.util.Optional;

/**
 * 用户服务实现类
 * 实现UserService接口定义的用户相关业务操作
 */
@Service
public class UserServiceImpl extends UserDetailsServiceImpl implements UserService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private JwtTokenProvider tokenProvider;

    @Autowired
    private RestTemplate restTemplate;

    @Override
    @Transactional
    public boolean register(RegisterDTO registerDTO) {
        // 检查用户名是否已存在
        if (userRepository.existsByUsername(registerDTO.getUsername())) {
            return false;
        }

        // 检查邮箱是否已存在
        if (userRepository.existsByEmail(registerDTO.getEmail())) {
            return false;
        }

        // 创建用户对象
        User user = new User();
        user.setUsername(registerDTO.getUsername());
        user.setPassword(passwordEncoder.encode(registerDTO.getPassword()));
        user.setEmail(registerDTO.getEmail());
        user.setPhone(registerDTO.getPhone());
        user.setType(User.UserType.valueOf(registerDTO.getType()));
        user.setMembershipStatus(User.MembershipStatus.FREE);
        user.setStatus(User.AccountStatus.ACTIVE);
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());

        // 保存用户
        userRepository.updateById(user);
        return true;
    }

    @Override
    public String login(LoginDTO loginDTO) {
        // 进行身份验证
        Authentication authentication = authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(
                        loginDTO.getUsername(),
                        loginDTO.getPassword()
                )
        );

        // 设置安全上下文
        SecurityContextHolder.getContext().setAuthentication(authentication);

        // 更新用户最后登录时间
        User user = userRepository.findByUsername(loginDTO.getUsername())
            .orElseThrow(() -> new UsernameNotFoundException("User not found with username: " + loginDTO.getUsername()));
        user.setLastLoginTime(LocalDateTime.now());
  
        userRepository.updateById(user);

        // 生成JWT Token
        return tokenProvider.generateToken(authentication);
    }

    @Override
    public String loginByPhonePassword(String phone, String password) {
        User user = userRepository.findByPhone(phone)
                .orElseThrow(() -> new UsernameNotFoundException("手机号不存在"));

        if (!passwordEncoder.matches(password, user.getPassword())) {
            throw new RuntimeException("密码错误");
        }

        return authenticateAndGenerateToken(user);
    }

    @Override
    public String loginBySmsCode(String phone, String smsCode) {
        User user = userRepository.findByPhone(phone)
                .orElseThrow(() -> new UsernameNotFoundException("手机号不存在"));

        if (user.getSmsCode() == null || !user.getSmsCode().equals(smsCode) || 
                user.getSmsCodeExpireTime() == null || new Date().after(user.getSmsCodeExpireTime())) {
            throw new RuntimeException("验证码无效或已过期");
        }

        // 验证成功后清除验证码
        user.setSmsCode(null);
        user.setSmsCodeExpireTime(null);
        return authenticateAndGenerateToken(user);
    }

    @Override
    public String loginByWechat(String code) {
        // 调用微信API获取openid
        String appId = "your_wechat_appid";
        String secret = "your_wechat_secret";
        String url = String.format("https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code",
                appId, secret, code);

        Map<String, String> response = restTemplate.getForObject(url, Map.class);
        String openId = response.get("openid");
        if (openId == null) {
            throw new RuntimeException("微信登录失败");
        }

        return handleThirdPartyLogin(openId, null, "wechat");
    }

    @Override
    public String loginByAlipay(String authCode) {
        // 调用支付宝API获取用户ID
        String appId = "your_alipay_appid";
        String privateKey = "your_private_key";
        // 实际开发中需使用支付宝SDK处理签名和请求
        String userId = "alipay_user_id_from_api";// 模拟获取用户ID

        return handleThirdPartyLogin(null, userId, "alipay");
    }

    @Override
    public boolean sendSmsCode(String phone) {
        User user = userRepository.findByPhone(phone)
                .orElseThrow(() -> new UsernameNotFoundException("手机号不存在"));

        // 生成6位验证码
        String code = String.format("%06d", new Random().nextInt(999999));
        user.setSmsCode(code);
        // 设置5分钟过期
        Date expireTime = new Date(System.currentTimeMillis() + 5 * 60 * 1000);
        user.setSmsCodeExpireTime(expireTime);
        userRepository.insert(user);

        // 调用短信服务发送验证码（实际实现需对接短信API）
        System.out.println("发送短信验证码: " + code + " 到手机: " + phone);
        return true;
    }

    @Override
    public void updateMembershipExpiry(Long userId, Date startTime, Date endTime) {
        User user = userRepository.selectById(userId)
            .orElseThrow(() -> new RuntimeException("User not found with id: " + userId));
        
        user.setMembershipStartTime(startTime);
        user.setMembershipEndTime(endTime);
        user.setMembershipStatus(User.MembershipStatus.PREMIUM);
        
        userRepository.insert(user);
    }

    @Override
    public User getUserById(Long id) {
        return userRepository.selectById(id);
    }

    // 辅助方法：处理第三方登录公共逻辑
    private String handleThirdPartyLogin(String wechatOpenId, String alipayUserId, String type) {
        User user = null;
        if ("wechat".equals(type)) {
            user = userRepository.findByWechatOpenId(wechatOpenId).orElse(null);
        } else if ("alipay".equals(type)) {
            user = userRepository.findByAlipayUserId(alipayUserId).orElse(null);
        }

        // 新用户自动注册
        if (user == null) {
            user = new User();
            user.setUsername(type + "_" + (wechatOpenId != null ? wechatOpenId : alipayUserId).substring(0, 10));
            user.setPassword(passwordEncoder.encode("random_password"));// 随机密码
            user.setPhone("");
            user.setEmail(type + "_" + System.currentTimeMillis() + "@mapaower.com");
            user.setType(User.UserType.DEVELOPER);
            user.setMembershipStatus(User.MembershipStatus.FREE);
            user.setStatus(User.AccountStatus.ACTIVE);
            user.setWechatOpenId(wechatOpenId);
            user.setAlipayUserId(alipayUserId);
            user.setCreateTime(LocalDateTime.now());
            user.setUpdateTime(LocalDateTime.now());
            userRepository.insert(user);
        }

        return authenticateAndGenerateToken(user);
    }

    // 辅助方法：认证并生成token
    private String authenticateAndGenerateToken(User user) {
        // 更新最后登录时间
        user.setLastLoginTime(LocalDateTime.now());
        userRepository.updateById(user);

        // 创建认证对象
        UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
                user.getUsername(), null, null);
        SecurityContextHolder.getContext().setAuthentication(authentication);

        // 生成JWT Token
        return tokenProvider.generateToken(authentication);
    }

    @Override
    public User getUserByUsername(String username) {
        Optional<User> optionalUser = userRepository.findByUsername(username);
        return optionalUser.orElse(null);
    }

    @Override
    @Transactional
    public boolean updateProfile(Long id, UpdateProfileDTO updateProfileDTO) {
        User dbUser = userRepository.selectById(id);
        if (dbUser == null) {
            return false;
        }
        
        // 更新用户信息
        if (updateProfileDTO.getUsername() != null && !updateProfileDTO.getUsername().equals(dbUser.getUsername())) {
            if (userRepository.existsByUsername(updateProfileDTO.getUsername())) {
                return false;
            }
            dbUser.setUsername(updateProfileDTO.getUsername());
        }
        
        if (updateProfileDTO.getEmail() != null && !updateProfileDTO.getEmail().equals(dbUser.getEmail())) {
            if (userRepository.existsByEmail(updateProfileDTO.getEmail())) {
                return false;
            }
            dbUser.setEmail(updateProfileDTO.getEmail());
        }
        
        if (updateProfileDTO.getPhone() != null) {
            dbUser.setPhone(updateProfileDTO.getPhone());
        }
        
        if (updateProfileDTO.getMembershipStatus() != null) {
            dbUser.setMembershipStatus(User.MembershipStatus.valueOf(updateProfileDTO.getMembershipStatus()));
        }
        
        if (updateProfileDTO.getStatus() != null) {
            dbUser.setStatus(User.AccountStatus.valueOf(updateProfileDTO.getStatus()));
        }
        
        dbUser.setUpdateTime(LocalDateTime.now());
        userRepository.updateById(dbUser);
        return true;
    }

    @Override
    @Transactional
    public boolean updatePassword(Long id, String oldPassword, String newPassword) {
        User dbUser = userRepository.selectById(id);
        if (dbUser == null) {
            return false;
        }

        // 验证旧密码
        if (!passwordEncoder.matches(oldPassword, dbUser.getPassword())) {
            return false;
        }
        
        // 更新密码
        dbUser.setPassword(passwordEncoder.encode(newPassword));
        dbUser.setUpdateTime(LocalDateTime.now());
        
        // 保存更新后的用户信息
        userRepository.updateById(dbUser);
        return true;
    }

    @Override
    @Transactional
    public boolean disableUser(Long id) {
        User dbUser = userRepository.selectById(id);
        if (dbUser == null) {
            return false;
        }

        dbUser.setStatus(User.AccountStatus.LOCKED);
        dbUser.setUpdateTime(LocalDateTime.now());
        
        userRepository.updateById(dbUser);
        return true;
    }

    @Override
    @Transactional
    public boolean enableUser(Long id) {
        User dbUser = userRepository.selectById(id);
        if (dbUser == null) {
            return false;
        }
        dbUser.setStatus(User.AccountStatus.ACTIVE);
        dbUser.setUpdateTime(LocalDateTime.now());
        userRepository.updateById(dbUser);
        return true;
    }



 

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(username)
            .orElseThrow(() -> new UsernameNotFoundException("User not found with username: " + username));

// 由于 UserPrincipal(User) 构造函数未定义，推测可能需要使用用户信息构造 UserDetails 对象
// 以下基于 Spring Security 的 User 类创建 UserDetails 对象
return org.springframework.security.core.userdetails.User.builder()
        .username(user.getUsername())
        .password(user.getPassword())
        .roles(user.getType().name()) // 假设用户类型作为角色
        .build();
    }
}